package com.lyf.scm.plan.domain.service.impl;

import com.lyf.scm.common.enums.ResponseMsg;
import com.lyf.scm.common.enums.SkuUnitTypeEnum;
import com.lyf.scm.common.enums.TiSsEnum;
import com.lyf.scm.plan.api.dto.OtherTargetEchartResultDTO;
import com.lyf.scm.plan.api.dto.OtherTargetGeneralQueryDTO;
import com.lyf.scm.plan.api.dto.OtherTargetResultDTO;
import com.lyf.scm.plan.domain.remote.bigdata.dto.TiSsStockQueryDTO;
import com.lyf.scm.plan.domain.remote.bigdata.dto.TiSsStockResultDTO;
import com.lyf.scm.plan.domain.service.CommonService;
import com.lyf.scm.plan.domain.service.UrgentReplishmentService;
import com.rome.arch.core.exception.RomeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description:
 *
 * @author: haodong
 * @data: 2020/11/23 10:59
 */
@Slf4j
@Service
public class UrgentReplishmentServiceImpl implements UrgentReplishmentService {

    @Resource
    private CommonService commonService;

    @Override
    public OtherTargetResultDTO getResult(OtherTargetGeneralQueryDTO otherTargetQuery, Map<String, BigDecimal> unitMap) {
        return null;
    }

    @Override
    public List<OtherTargetResultDTO> getBatchResult(OtherTargetGeneralQueryDTO paramData, Map<String, BigDecimal> unitMap) {
        List<TiSsStockQueryDTO> query = this.getQuery(paramData);
        Long unitType = paramData.getUnitType();
        return this.getTiSsStock(query, paramData.getDateList(), unitMap, unitType);
    }

    private List<TiSsStockQueryDTO> getQuery(OtherTargetGeneralQueryDTO otherTargetQuery) {
        List<TiSsStockQueryDTO> paramList = new ArrayList<>();
        for (String deliverId : otherTargetQuery.getDeliverIds()) {
            TiSsStockQueryDTO param = new TiSsStockQueryDTO();
            param.setStartDate(otherTargetQuery.getStartDate());
            param.setEndDate(otherTargetQuery.getEngDate());
            param.setStore(deliverId);
            param.setPageNo(1);
            param.setPageSize(3000);
            List<String> skuList = otherTargetQuery.getSkuList();
            if (CollectionUtils.isNotEmpty(skuList)) {
                String skuArrStr = skuList.toString();
                param.setSkuKey(skuArrStr.substring(1, skuArrStr.length() - 1));
            }
            paramList.add(param);
        }
        return paramList;
    }


    @Override
    public OtherTargetEchartResultDTO getEchartResult(OtherTargetGeneralQueryDTO paramData) {
        return null;
    }

    @Override
    public List<OtherTargetEchartResultDTO> getBatchEchartResult(OtherTargetGeneralQueryDTO paramData) {
        List<TiSsStockQueryDTO> query = this.getQuery(paramData);
        return this.getEchartTiSsStock(query, paramData.getDateList());
    }

    public List<OtherTargetResultDTO> getTiSsStock(List<TiSsStockQueryDTO> queryList, List<String> dateList, Map<String, BigDecimal> unitMap, Long unitType) {
        List<OtherTargetResultDTO> resultList = new ArrayList<>();
        for (TiSsStockQueryDTO query : queryList) {
            //循环调用获取
            List<TiSsStockResultDTO> thirteenWeekPredictSale = commonService.thirteenWeekPredictSale(query);
            if (CollectionUtils.isEmpty(thirteenWeekPredictSale)) {
                continue;
            }
            resultList.addAll(parsingData(thirteenWeekPredictSale, dateList, unitMap, unitType));
        }
        if (CollectionUtils.isEmpty(resultList)) {
            return getNullResult(queryList, dateList);
        }
        return resultList;
    }

    private List<OtherTargetResultDTO> getNullResult(List<TiSsStockQueryDTO> queryList, List<String> dateList) {
        List<OtherTargetResultDTO> resultList = new ArrayList<>();
        for (TiSsStockQueryDTO val : queryList) {
            String[] skuList = val.getSkuKey().split(",");
            for (String sku : skuList) {
                // 安全库存
                resultList.add(getNullResultEntity(val, sku, dateList, TiSsEnum.STOCK_SAFETY));
                //目标库存
                resultList.add(getNullResultEntity(val, sku, dateList, TiSsEnum.TARGET_INVENTORY));
                // 覆盖天数
                resultList.add(getNullResultEntity(val, sku, dateList, TiSsEnum.COVERED_DAYS));
            }

        }
        return resultList;
    }

    private OtherTargetResultDTO getNullResultEntity(TiSsStockQueryDTO query, String sku, List<String> dateList, TiSsEnum tiSsStock) {
        Map<String, List<BigDecimal>> resultMap = new HashMap<>();
        // 取值Key 仓id + skuCode
        String key = query.getStore() + sku;
        // 指标集合
        List<BigDecimal> targetList = new ArrayList<>();
        dateList.forEach(val -> targetList.add(BigDecimal.ZERO));

        resultMap.put(key, targetList);

        OtherTargetResultDTO result = new OtherTargetResultDTO();
        result.setOtherTargetsEnum(tiSsStock);
        result.setResult(resultMap);
        return result;
    }

    private List<OtherTargetResultDTO> parsingData(List<TiSsStockResultDTO> tiSsStockResultList, List<String> dateList, Map<String, BigDecimal> unitMap, Long unitType) {
        List<OtherTargetResultDTO> resultList = new ArrayList<>();
        for (TiSsStockResultDTO tiSsStockResult : tiSsStockResultList) {
            // 安全库存
            resultList.add(getResultEntity(tiSsStockResult, dateList, TiSsEnum.STOCK_SAFETY, unitMap, unitType));
            //目标库存
            resultList.add(getResultEntity(tiSsStockResult, dateList, TiSsEnum.TARGET_INVENTORY, unitMap, unitType));
            // 覆盖天数
            resultList.add(getResultEntity(tiSsStockResult, dateList, TiSsEnum.COVERED_DAYS, unitMap, unitType));
        }
        return resultList;
    }

    private OtherTargetResultDTO getResultEntity(TiSsStockResultDTO tiSsStockResult, List<String> dateList, TiSsEnum tiSsStock, Map<String, BigDecimal> unitMap, Long unitType) {
        Map<String, List<BigDecimal>> resultMap = new HashMap<>();
        // 取值Key 仓id + skuCode
        String key = tiSsStockResult.getNodeId() + tiSsStockResult.getSkuKey();
        // 指标集合
        List<BigDecimal> targetList = new ArrayList<>();
        String unitKey = tiSsStockResult.getSkuKey() + SkuUnitTypeEnum.BASIS_UNIT.getUnitType() + unitType;
        dateList.forEach(val -> {
            if (val.equals(tiSsStockResult.getStartDate())) {
                if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(unitType)) {
                    targetList.add(new BigDecimal(tiSsStockResult.getSs()).multiply(unitMap.get(unitKey)).setScale(3,BigDecimal.ROUND_HALF_UP));
                } else {
                    targetList.add(new BigDecimal(tiSsStockResult.getSs()));
                }
            } else {
                targetList.add(BigDecimal.ZERO);
            }
        });
        resultMap.put(key, targetList);
        OtherTargetResultDTO result = new OtherTargetResultDTO();
        result.setOtherTargetsEnum(tiSsStock);
        result.setResult(resultMap);
        return result;
    }

    @Override
    public List<OtherTargetEchartResultDTO> getEchartTiSsStock(List<TiSsStockQueryDTO> queryList, List<String> dateList) {
        List<OtherTargetEchartResultDTO> resultList = new ArrayList<>();
        for (TiSsStockQueryDTO query : queryList) {
            //循环调用获取
            List<TiSsStockResultDTO> thirteenWeekPredictSale = commonService.thirteenWeekPredictSale(query);
            resultList.addAll(parsingEchartData(thirteenWeekPredictSale, dateList));
        }
        if (CollectionUtils.isEmpty(resultList)) {
            resultList.add(getechartNullResult(dateList, TiSsEnum.STOCK_SAFETY));
            resultList.add(getechartNullResult(dateList, TiSsEnum.TARGET_INVENTORY));
            resultList.add(getechartNullResult(dateList, TiSsEnum.COVERED_DAYS));
            return resultList;
        }
        return resultList;
    }

    private OtherTargetEchartResultDTO getechartNullResult(List<String> dateList, TiSsEnum tiSsEnum) {
        List<BigDecimal> targetList = new ArrayList<>();
        dateList.forEach(v -> targetList.add(BigDecimal.ZERO));
        OtherTargetEchartResultDTO result = new OtherTargetEchartResultDTO();
        result.setOtherTargetsEnum(tiSsEnum);
        result.setResult(targetList);
        return result;
    }

    private List<OtherTargetEchartResultDTO> parsingEchartData(List<TiSsStockResultDTO> tiSsStockResultList, List<String> dateList) {
        List<OtherTargetEchartResultDTO> resultList = new ArrayList<>();
        // 安全库存
        resultList.add(getEchartResultEntity(tiSsStockResultList, dateList, TiSsEnum.STOCK_SAFETY));
        //目标库存
        resultList.add(getEchartResultEntity(tiSsStockResultList, dateList, TiSsEnum.TARGET_INVENTORY));
        // 覆盖天数
        resultList.add(getEchartResultEntity(tiSsStockResultList, dateList, TiSsEnum.COVERED_DAYS));
        return resultList;
    }

    private OtherTargetEchartResultDTO getEchartResultEntity(List<TiSsStockResultDTO> tiSsStockResultList, List<String> dateList, TiSsEnum tiSsEnum) {
        // 指标集合
        List<BigDecimal> targetList = new ArrayList<>();
        dateList.forEach(date ->
                targetList.add(
                        tiSsStockResultList.stream()
                                .filter(val -> val.getStartDate().equals(date))
                                .map(e -> {
                                    switch (tiSsEnum.getType()) {
                                        case 1:
                                            return new BigDecimal(e.getSs());
                                        case 2:
                                            return new BigDecimal(e.getTi());
                                        case 3:
                                            return new BigDecimal(e.getTargetDays());
                                        default:
                                            throw new RomeException(ResponseMsg.PARAM_ERROR.getCode(), ResponseMsg.PARAM_ERROR.getMsg());
                                    }
                                }).reduce(BigDecimal.ZERO, BigDecimal::add)
                )
        );
        OtherTargetEchartResultDTO result = new OtherTargetEchartResultDTO();
        result.setOtherTargetsEnum(tiSsEnum);
        result.setResult(targetList);
        return result;
    }
}
